/*
THIS FILE IS PART OF THE >>ADRENALIN-3D-GRAFIC-ENGINE<<
for latest info visit http://www.creative-games.de

Copyright (c) 2008-2009 by Marco Schneider

This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License (LGPL) as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

*/

#ifndef __ADL_MATH_VECTOR2_H__
#define __ADL_MATH_VECTOR2_H__

#include "../Defines.h"

namespace Adrenalin
{
	namespace Math
	{
		template<typename T=float>
		struct ADRENALIN_API Vector2
		{
			union
			{
				struct	{
					T x, y;
				};
				T v[2];
			};

			#pragma region Constructors
			//Constructors:
			Vector2() 
			{}
			Vector2( T fX, T fY ) 
				: x(fX), y(fY)
			{}
			Vector2( T f[2] ) 
				: x(f[0]), y(f[1]) 
			{}
			#pragma endregion

			#pragma region Operators
			operator T*	()	{	return v;	}
			operator const T*	()	const	{	return v;	}

			Vector2& operator = ( const T& inX )	{ x=y=inX;	return *this; }
			Vector2& operator += ( const Vector2& inVec )	{ x += inVec.x; y += inVec.y; return *this; }
			Vector2& operator -= ( const Vector2& inVec )	{ x -= inVec.x; y -= inVec.y; return *this; }
			Vector2& operator *= ( const Vector2& inVec )	{ x *= inVec.x; y *= inVec.y; return *this; }
			Vector2& operator /= ( const Vector2& inVec )	{ x /= inVec.x, y /= inVec.y; return *this; }

			Vector2& operator + ( const Vector2& inVec ) const	{ return Vector2( x + inVec.x, y + inVec.y ); }
			Vector2& operator - ( const Vector2& inVec ) const	{ return Vector2( x - inVec.x, y - inVec.y ); }
			Vector2& operator * ( const Vector2& inVec ) const	{ return Vector2( x * inVec.x, y * inVec.y ); }
			Vector2& operator * ( const T& scalar )	const { return Vector2( x * scalar, y * scalar );	}
			Vector2& operator / ( const Vector2& inVec ) const	{ return Vector2( x / inVec.x, y / inVec.y ); }
			Vector2& operator / ( const T& scalar )	const {	return Vector2( x / scalar, y / scalar ); }

			Vector2& operator - () { return Vector2( -x,-y ); }
			#pragma endregion

			#pragma region Methodes
			/// Normalize the Vector
			Vector2& Normalize( void )
			{
				T tLength = GetLength();
				if(tLength==0)
					return *this;

				tLength = 1.0f / tLength;
				x *= tLength;
				y *= tLength;
				return *this;
			}
			/// Return Length of Vector
			T GetLength( void )	{ return sqrt(x*x + y*y); }
			/// Return the Dotproduct between this and a given Vector
			T DotProduct( const Vector2& inVec ) const {	return x*inVec.x + y*inVec.y;	}
			/// Return if Vector is null
			bool IsNull( void )
			{
				if( (x == 0) && (y == 0) ) {
					return true;
				} else {
					return false;
				}
			}

			#pragma endregion
		};
	}//namespace Math
}//namespace Adrenalin

#endif